/**
	Author: Nathan
*/
#include "gtest/gtest.h"
#include "gmock\gmock.h"
#include "FeederAgentMock.h"
#include "NestAgentMock.h"
#include "GUILaneMock.h"
#include "LaneAgent.h"

class LaneAgentTest : public ::testing::Test {

protected:

  LaneAgentTest() : agent("Lane Agent") {

  }
	
  virtual void SetUp() {
	  agent.testing = true;
	  agent.setFeeder(&feeder);
	  agent.setNest(&nest); 
	  agent.setGUI(&guiLane);
  }

  LaneAgent agent;

  FeederAgentMock feeder;

  NestAgentMock nest;

  GUILaneMock guiLane;
  
  bool runScheduler(){
    return agent.pickAndExecuteAnAction();
  }
  
  int mySpeed() {
	return agent.laneSpeed;
  }

  int factorySpeed() {
	  return agent.factorySpeed;
  }
  
  LaneAgent::LaneState myState() {
	return agent.state;
  }
  
  PartType myPartType() {
	return agent.partType;
  }

  /*Agent::ClientStatus getNextStat(){
	  return agent->nextStatus;
  }*/
};

TEST_F(LaneAgentTest, InitialTest){
	EXPECT_EQ(mySpeed(),5);
	EXPECT_EQ(factorySpeed(), 33);
	EXPECT_EQ(myState(),LaneAgent::LaneState::None);
	EXPECT_EQ(myPartType(),PartType::EMPTY);
}

TEST_F(LaneAgentTest, SchedulerReturnTestWOPartType){
	EXPECT_EQ(runScheduler(),false);
}

TEST_F(LaneAgentTest, TestingSettingPartTypeFromNest){
	PartType partA = PartType::A;
	EXPECT_EQ(myPartType(),PartType::EMPTY);
	agent.msgPleaseGetParts(partA);
	EXPECT_EQ(myPartType(),partA);
}

TEST_F(LaneAgentTest, SwitchToPurgingStateAndStopPurgingInNest){
	PartType partA = PartType::A;
	agent.msgPleaseGetParts(partA);
	EXPECT_EQ(myPartType(),partA);
	EXPECT_EQ(myState(),LaneAgent::LaneState::Purge);
	EXPECT_EQ(runScheduler(),true);
	EXPECT_CALL(nest, msgPleaseStopPurging());
	agent.informPurgingComplete();
	EXPECT_FALSE(runScheduler());
}

TEST_F(LaneAgentTest, InformingTheNestItShouldBeFull){
	PartType partA = PartType::A;
	EXPECT_FALSE(runScheduler());
	agent.msgHereAreParts(partA);
	EXPECT_FALSE(runScheduler());
	EXPECT_CALL(nest,msgIThinkYoureFull());
	agent.tellNestItIsFull();
	EXPECT_FALSE(runScheduler());
}

TEST_F(LaneAgentTest, RequestForSamePartsFromNestToFeeder){
	PartType partA = PartType::A;
	EXPECT_FALSE(runScheduler());
	agent.msgPleaseGetParts(partA);
	EXPECT_TRUE(runScheduler());
	agent.msgPleaseGetParts(partA);
	EXPECT_EQ(myState(), LaneAgent::LaneState::Request_More_Parts);
	EXPECT_CALL(feeder, msgPleaseGetParts(partA,&agent));
	EXPECT_TRUE(runScheduler());
}